嗨咿,我是 illumi!
上篇文章你可能覺得gsap 移動只能往一個方向,今天來試著讓物件往不同方向飛,快樂爆炸吧~
一樣是用TS + React + Tailwind示範~
背後的邏輯其實是這樣:
scale = 0
→ 看不到opacity = 0
→ 透明x = 0, y = 0
→ 都在同一個位置scale = 1
→ 放大到正常大小opacity = 1
→ 顯示出來x, y
→ 飛到不同座標(像爆炸一樣散開)因為我想要控制圖片目的地位置,所以先寫好,當然也可以換成隨機的,但效果就比較不可控:
interface DecorConfig {
top: number; // y 位置(百分比)
left: number; // x 位置(百分比)
size: number; // 圖片尺寸(px)
}
const decorPositions: DecorConfig[] = [
{ top: 10, left: 20, size: 48 },
{ top: 20, left: 70, size: 76 },
...
];
<div ref={decorRef}>
<img
key=?
src=?
alt=""
className="absolute"
style={{
top: `${decorPositions[i].top}%`,
left: `${decorPositions[i].left}%`,
height: `${decorPositions[i].size}px`,
rotate: `${Math.random() * 90 - 10}deg`,
}}
/>
</div>
一樣最外層有 ref={} 讓GSAP 控制
const decorRef = useRef<HTMLDivElement>(null);
useGSAP(
() => {
const images = decorRef.current?.children;
if (!images || !images.length) return;
gsap.fromTo(
images,
{
x: 0,
y: 0,
scale: 0,
opacity: 0,
},
{
opacity: 1,
scale: 1,
x: (i) => decorPositions[i].left - 50,
y: (i) => decorPositions[i].top - 50,
width: (i) => decorPositions[i].size,
height: (i) => decorPositions[i].size,
duration: 1,
ease: "back.out(1.7)",
stagger: 0.05,
}
);
},
{ dependencies: [currentIndex], scope: decorRef }
);
fromTo
:指定動畫的起始狀態 (from
) 與目標狀態 (to
)scale: 0 → 1
:物件從無到有,產生「飛出」感opacity: 0 → 1
:淡入效果stagger
:每張圖延遲 0.05 秒,形成連鎖爆炸效果-50
?x: (i) => decorPositions[i].left - 50,
y: (i) => decorPositions[i].top - 50,
這裡是 座標修正,原因如下:
left = 20%
,物件的左上角會在容器的 20% 位置。size
),如果不修正,飛出的動畫看起來會「跑偏」50
這個數字是大約的中心偏移量,讓 GSAP 的 x/y
最終目標落在裝飾圖的中心位置
我們明天再見吧~